<?php
// 应用公共函数库文件
use think\Request;
use think\Cache;
use think\Session;
use app\common\model\Wxapp as WxappModel;
use app\common\model\StoreUser as StoreUserModel;
use app\common\model\ShopClerk as ShopClerkModel;
use app\common\model\Order as OrderModel;
use app\common\model\User as UserModel;
use app\common\model\Dealer as DealerModel;
use app\common\model\Setting as SettingModel;
use app\common\model\Config as ConfigModel;
use app\common\model\Wechat as WechatModel;
use app\common\model\WebWxappPlugins as WebWxappPluginsModel;
use app\common\model\WechatErr;
use app\common\model\WebSet;
use app\common\library\wechat\WxPay;

	/**
	 * 商家自动接单与配送
	 */
	function auto_delivery($order_id)
	{
		$order = OrderModel::detail($order_id);
		if($order['shop']['is_order']['value'] == 1){
			$order->setShopStatus();//商家接单
		}
		if($order['order_mode']['value']==20 AND $order['shop']['is_delivery']['value'] == 1){
			$order->setDelivery($order['shop']['delivery_id']);//外卖自动推送订单
		}
		return true;
	}
	
	/**
	 * 全局验证
	 * model=模块 0超管 1商户 2代理
	 */
	function checking($model=0)
	{
		//超管验证
		if($model==0){
			$admin = Session::get('hema_admin');
			if($admin['user']['store_user_id'] == 0){
				return '体验用户不可操作！';
			}
			return false;
		}
		//商户验证
		if($model==1){
			$store = Session::get('hema_store');
			if($store['user']['user_name'] == 'test'){
				return '体验用户不可操作！';
			}
			return false;
		}
		//代理验证
		if($model==2){
			$agent = Session::get('hema_agent');
			if($agent['user']['store_user_id'] == 0){
				return '体验用户不可操作！';
			}
			return false;
		}
	}
	/**
	 * 发送模板消息
	 * @param  string $mode     receive=商家接单通知 horseman=骑手取货通知 delivery=订单配送通知 take=取餐提醒 finish=订单完成通知 refund=退款状态通知
	 * @param  [type] $order 订单
	 */
	function post_tpl($mode='',$order_id)
	{
		//获取订阅消息配置
		$order = OrderModel::detail($order_id);
		//获取订阅消息配置
		$values = SettingModel::getItem('wxapptpl',$order['wxapp_id']);
		$data = [];
		$template_id = '';
		//商家接单通知
		if($mode=='receive' AND !empty($values['receive'])){
			$template_id = $values['receive'];
			$data = [
				'thing2' => [
					'value' => $order['shop']['shop_name']//商家名称{{thing2.DATA}}
				],
				'character_string6' => [
					'value' => $order['order_no']//订单编号{{character_string6.DATA}}
				],
				'phrase7' => [
					'value' => '已接单' //订单状态{{phrase7.DATA}}
				],
				'phone_number10' => [
					'value' => date('Y-m-s h:i',time())//接单时间{{phone_number10.DATA}}
				],
				'thing5' => [
					'value' => '商家备餐中，点击查看详情>>' //温馨提示{{thing5.DATA}}
				]
			];
		}
		//骑手取货通知
		if($mode=='horseman' AND !empty($values['horseman'])){
			$template_id = $values['horseman'];
			$data = [
				'thing1' => [
					'value' => $order['shop']['shop_name']//商家{{thing1.DATA}}
				],
				'phrase2' => [
					'value' => '骑手已接单' //状态{{phrase2.DATA}}
				],
				'thing4' => [
					'value' => '待骑手配送，点击查看详情>>' //备注{{thing4.DATA}}
				]
			];
		}
		//取餐提醒
		if($mode=='take' AND !empty($values['take'])){
			$template_id = $values['take'];
			if($order['order_mode']['value']==30){
				$status = '到店自取';
			}else{
				$status = '堂食排号';
			}
			$data = [
				'thing23' => [
					'value' => $order['shop']['shop_name']//门店名称{{thing23.DATA}}
				],
				'character_string12' => [
					'value' => $order['row_no']//取餐编号{{character_string12.DATA}}
				],
				'phrase30' => [
					'value' => $status //订单类型{{phrase30.DATA}}
				],
				'phrase16' => [
					'value' => '待领取' //订单状态{{phrase16.DATA}}
				],
				'thing7' => [
					'value' => '请前往领餐处，点击查看详情>>' //温馨提醒{{thing7.DATA}}
				]
			];
		}
		//订单配送通知
		if($mode=='delivery' AND !empty($values['delivery'])){
			$template_id = $values['delivery'];
			$data = [
				'thing1' => [
					'value' => $order['shop']['shop_name']//出餐门店{{thing1.DATA}}
				],
				'character_string2' => [
					'value' => $order['order_no']//订单号{{character_string2.DATA}}
				],
				'phrase15' => [
					'value' => '配送中' //订单状态{{phrase15.DATA}}
				],
				'time4' => [
					'value' => date('Y-m-s h:i',time())//送出时间{{time4.DATA}}
				],
				'thing5' => [
					'value' => '30分钟内送达，点击查看详情>>' //备注{{thing5.DATA}}
				]
			];
		}
		//订单完成通知
		if($mode=='finish' AND !empty($values['finish'])){
			$template_id = $values['finish'];
			if($order['order_mode']['value']==30){
				$status = '到店自取';
			}else{
				if($order['row_no'] == ''){
					$status = '堂食扫码';
				}else{
					$status = '堂食排号';
				}
			}
			$data = [
				'thing13' => [
					'value' => $order['shop']['shop_name']//门店名称{{thing13.DATA}}
				],
				'phrase11' => [
					'value' => '已完成'//订单状态{{phrase11.DATA}}
				],
				'thing14' => [
					'value' => $status //订单类型{{thing14.DATA}}
				],
				'time12' => [
					'value' => date('Y-m-s h:i',time())//完成时间{{time12.DATA}}
				],
				'thing5' => [
					'value' => '订单餐食已送完，点击查看详情>>' //备注{{thing5.DATA}}
				]
			];
		}
		//退款状态通知
		if($mode=='refund' AND !empty($values['refund'])){
			$template_id = $values['refund'];
			if($order['refund_status']['value']==20){
				$status = '退款成功';
				$msg = '退款已原路返回，点击查看详情>>';
			}else{
				$status = '退款失败';
				$msg = '不符合退款要求，点击查看详情>>';
			}
			$data = [
				'phrase1' => [
					'value' => $status//退款状态 {{phrase1.DATA}}
				],
				'amount2' => [
					'value' => '￥'.$order['refund_price'].'元'//退款金额 {{amount2.DATA}}
				],
				'time4' => [
					'value' => date('Y-m-s h:i',time()) //处理时间 {{time4.DATA}}
				],
				'thing5' => [
					'value' => $msg //温馨提示 {{thing5.DATA}}
				]
			];
		}
		//发送订阅消息
		if(sizeof($data) >0 AND $template_id != ''){
			$access_token = getAccessToken($order['wxapp_id']);
			$url = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token='.$access_token;
			$data = [
				'touser' => $order['user']['open_id'],
				'template_id' => $template_id,
				'page' => 'pages/order/detail?order_id='.$order_id,
				'data' => $data
			];
			$result = json_decode(http_post($url,$data),true);	
		}
		return true;
	}
	
	/**
	 * 商户管理员 - 账户资金变动提醒 - 公众号
	 */
	function sand_account_change_msg($title,$pay,$surplus,$store_user_id)
	{ 
		$tplmsg = WebSet::getItem('tplmsg');	//获取模板消息编号
		if(empty($tplmsg['balance']['template_id'])){
			return true;
		}
		$wxapp = WebSet::getItem('wxapp');	//获取商家助手小程序
		$msg = [
			'touser' => '',
			'template_id' => $tplmsg['balance']['template_id'],
			'miniprogram' => [
				'appid' => $wxapp['app_id'],
				'pagepath' => 'pages/index/index'
			],
			'data' => [
				'first' => [
					'value' => '请您核实下列项目',
					'color' => '#173177'
				],
				'keyword1' => [
					'value' => $title,//交易类型
					'color' => '#173177'
				],
				'keyword2' => [
					'value' => '￥'.$pay.'元',//交易金额
					'color' => '#173177'
				],
				'keyword3' => [
					'value' => date('Y/m/d H:i:s',time()),//交易时间
					'color' => '#173177'
				],
				'keyword4' => [
					'value' => '￥'.$surplus.'元',//账户余额
					'color' => '#173177'
				],
				'remark' => [
					'value' => '如有疑问请及时联系我们!',
					'color' => '#173177'
				]
			]
		];
		return send_wechat_msg($msg,$store_user_id);
	}
	
	/**
	 * 商户管理员 - 申请受理通知 - 公众号
	 */
	function sand_apply_msg($name,$title,$store_user_id)
	{
		$tplmsg = WebSet::getItem('tplmsg');	//获取模板消息编号
		if(empty($tplmsg['apply']['template_id'])){
			return true;
		}
		$wxapp = WebSet::getItem('wxapp');	//获取商家助手小程序
		$msg = [
			'touser' => '',
			'template_id' => $tplmsg['apply']['template_id'],
			'miniprogram' => [
				'appid' => $wxapp['app_id'],
				'pagepath' => 'pages/index/index'
			],
			'data' => [
				'first' => [
					'value' => '您的导购申请已受理',
					'color' => '#173177'
				],
				'keyword1' => [
					'value' => $name,//申请人
					'color' => '#173177'
				],
				'keyword2' => [
					'value' => $title,//类型
					'color' => '#173177'
				],
				'keyword3' => [
					'value' => date('Y/m/d H:i:s',time()),//时间
					'color' => '#173177'
				],
				'remark' => [
					'value' => '感谢您的支持！',
					'color' => '#173177'
				]
			]
		];
		return send_wechat_msg($msg,$store_user_id);
	}
	
	/**
	 * 商户管理员 - 申请状态更新通知 - 公众号
	 */
	function sand_examine_msg($id,$title,$status,$store_user_id)
	{
		$tplmsg = WebSet::getItem('tplmsg');	//获取模板消息编号
		if(empty($tplmsg['examine']['template_id'])){
			return true;
		}
		$wxapp = WebSet::getItem('wxapp');	//获取商家助手小程序
		$msg = [
			'touser' => '',
			'template_id' => $tplmsg['examine']['template_id'],
			'miniprogram' => [
				'appid' => $wxapp['app_id'],
				'pagepath' => 'pages/index/index'
			],
			'data' => [
				'first' => [
					'value' => '最新申请状态',
					'color' => '#173177'
				],
				'keyword1' => [
					'value' => $title,//申请类型
					'color' => '#173177'
				],
				'keyword2' => [
					'value' => $id,//申请编号
					'color' => '#173177'
				],
				'keyword3' => [
					'value' => date('Y/m/d H:i:s',time()),//申请时间
					'color' => '#173177'
				],
				'keyword4' => [
					'value' => $status,//当前状态
					'color' => '#173177'
				],
				'remark' => [
					'value' => '请及时关注新的动态提醒。',
					'color' => '#173177'
				]
			]
		];
		return send_wechat_msg($msg,$store_user_id);
	}

	/**
	 * 商户管理员 - 试用申请成功通知 - 公众号
	 */
	function sand_testing_msg($title,$time,$store_user_id)
	{
		$tplmsg = WebSet::getItem('tplmsg');	//获取模板消息编号
		if(empty($tplmsg['testing']['template_id'])){
			return true;
		}
		$wxapp = WebSet::getItem('wxapp');	//获取商家助手小程序
		$msg = [
			'touser' => '',
			'template_id' => $tplmsg['testing']['template_id'],
			'miniprogram' => [
				'appid' => $wxapp['app_id'],
				'pagepath' => 'pages/index/index'
			],
			'data' => [
				'first' => [
					'value' => '恭喜您获得试用特权',
					'color' => '#173177'
				],
				'keyword1' => [
					'value' => $title,//申请项目
					'color' => '#173177'
				],
				'keyword2' => [
					'value' => date('Y/m/d H:i:s',$time),//有效期至
					'color' => '#173177'
				],
				'remark' => [
					'value' => '感谢您的使用。',
					'color' => '#173177'
				]
			]
		];
		return send_wechat_msg($msg,$store_user_id);
	}

	/**
	 * 商户骑手 - 抢单提醒 - 公众号
	 */
	function sand_grab_msg($order)
	{
		$tplmsg = WebSet::getItem('tplmsg');	//获取模板消息编号
		if(empty($tplmsg['grab']['template_id'])){
			return true;
		}
		$wxapp = WebSet::getItem('wxapp');	//获取商家助手小程序
		$msg = [
			'touser' => '',
			'template_id' => $tplmsg['grab']['template_id'],
			'miniprogram' => [
				'appid' => $wxapp['app_id'],
				'pagepath' => 'pages/order/index'
			],
			'data' => [
				'first' => [
					'value' => '您有新订单可抢单',
					'color' => '#173177'
				],
				'keyword1' => [
					'value' => $order['shop']['shop_name'],//商家名称
					'color' => '#173177'
				],
				'keyword2' => [
					'value' => $order['shop']['address'],//配送起点
					'color' => '#173177'
				],
				'keyword3' => [
					'value' => $order['address']['detail'],//配送终点
					'color' => '#173177'
				],
				'keyword4' => [
					'value' => $order['shop']['phone'],//商家电话
					'color' => '#173177'
				],
				'remark' => [
					'value' => '有疑问请联系商家，点击查看详情>>',
					'color' => '#173177'
				]
			]
		];
		$model = new ShopClerkModel;
		$clerk = $model->getLists($order['shop_id'],30,$order['wxapp_id']);	
		for($n=0;$n<sizeof($clerk);$n++){
			if($clerk[$n]['store_user_id'] > 0){
				send_wechat_msg($msg,$clerk[$n]['store_user_id']);
			}
		}
	}

	/**
	 * 商户店长 - 退款申请通知 - 公众号
	 */
	function sand_refund_msg($order)
	{
		$tplmsg = WebSet::getItem('tplmsg');	//获取模板消息编号
		if(empty($tplmsg['refund']['template_id'])){
			return true;
		}
		$wxapp = WebSet::getItem('wxapp');	//获取商家助手小程序
		$msg = [
			'touser' => '',
			'template_id' => $tplmsg['refund']['template_id'],
			'miniprogram' => [
				'appid' => $wxapp['app_id'],
				'pagepath' => 'pages/order/index'
			],
			'data' => [
				'first' => [
					'value' => '收到一条新退款, 请尽快受理',
					'color' => '#173177'
				],
				'keyword1' => [
					'value' => $order['shop']['shop_name'],//门店
					'color' => '#173177'
				],
				'keyword2' => [
					'value' => $order['order_no'],//订单编号
					'color' => '#173177'
				],
				'keyword3' => [
					'value' => '￥'.$order['refund_price'].'元',//退款金额
					'color' => '#173177'
				],
				'keyword4' => [
					'value' => date('Y/m/d H:i:s',time()),//退款时间
					'color' => '#173177'
				],
				'remark' => [
					'value' => $order['refund_desc'],
					'color' => '#173177'
				]
			]
		];
		$model = new ShopClerkModel;
		$clerk = $model->getLists($order['shop_id'],20,$order['wxapp_id']);	
		for($n=0;$n<sizeof($clerk);$n++){
			if($clerk[$n]['store_user_id'] > 0){
				send_wechat_msg($msg,$clerk[$n]['store_user_id']);
			}
		}
	}

	/**
	 * 商户店长 新订单提醒模板消息 - 公众号
	 */
	function sand_new_order_msg($order)
	{
		$tplmsg = WebSet::getItem('tplmsg');	//获取模板消息编号
		if(empty($tplmsg['new_order']['template_id'])){
			return true;
		}
		$wxapp = WebSet::getItem('wxapp');	//获取商家助手小程序
		if($order['order_mode']['value']==30){
			$title = '自取';
		}elseif($order['order_mode']['value']==20){
			$title = '外卖';
		}else{
			$title = '堂食';
		}
		$msg = [
			'touser' => '',
			'template_id' => $tplmsg['new_order']['template_id'],
			'miniprogram' => [
				'appid' => $wxapp['app_id'],
				'pagepath' => 'pages/order/index'
			],
			'data' => [
				'first' => [
					'value' => '收到一个新的'.$title.'订单',
					'color' => '#173177'
				],
				'keyword1' => [
					'value' => $order['order_no'],
					'color' => '#173177'
				],
				'keyword2' => [
					'value' => '￥'.$order['pay_price'].'元',
					'color' => '#173177'
				],
				'keyword3' => [
					'value' => $order['create_time'],
					'color' => '#173177'
				],
				'remark' => [
					'value' => '请及时处理您的订单。',
					'color' => '#173177'
				]
			]
		];
		$model = new ShopClerkModel;
		$clerk = $model->getLists($order['shop_id'],20,$order['wxapp_id']);	
		for($n=0;$n<sizeof($clerk);$n++){
			if($clerk[$n]['store_user_id'] > 0){
				send_wechat_msg($msg,$clerk[$n]['store_user_id']);
			}
		}
	}

	/**
	 * 发布模板消息 - 公众号
	 */
	function send_wechat_msg($msg,$store_user_id)
	{
		$store = StoreUserModel::detail($store_user_id);
		$msg['touser'] = $store['wechat_open_id'];
		$access_token = getAccessToken('',0);
		$url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$access_token;
		$res = http_post($url,$msg);
		return true;
	}
	
	/**
     * 分销-分账
     */
	function dealer($order_id){
		/*
		$order = OrderModel::getOrder($order_id);
		$order_price = $order['total_price'] - $order['activity_price'];//计算消费商品金额，不含餐盒等费用
		$second_price = 0; //二级佣金
		$first_money = 0; //一级佣金
		$set = SettingModel::getItem('dealer',$order['wxapp_id']);
		if($set['is_open']==1){
			$user = UserModel::getUser(['user_id' => $order['user_id']]);//获取上家用户
			if($user['recommender']['value']>0){
				$second_price = round($order_price*$set['second_money']/100,2);//计算二级佣金-四舍五入保留2位小数
				$second = UserModel::getUser(['user_id' => $user['recommender']['value']]);//获取二级上家用户
				if($second['recommender']['value']>0){
					$first_money = round($order_price*$set['first_money']/100,2);//计算一级佣金-四舍五入保留2位小数
					$first = UserModel::getUser(['user_id' => $second['recommender']['value']]);//获取一级上家用户
					$first->commission = ['inc',$first_money];
					$first->save();
					$model = new DealerModel;	//添加进账记录
					$model->save([
						'user_id' => $first['user_id'],
						'price' => $first_money,
						'order_id' => $order['order_id'],
						'wxapp_id' => $order['wxapp_id']
					]);
				}
				$second->commission = ['inc',$second_price];
				$second->save();
				$model = new DealerModel;	//添加进账记录
				$model->save([
					'user_id' => $second['user_id'],
					'price' => $second_price,
					'order_id' => $order['order_id'],
					'wxapp_id' => $order['wxapp_id']
				]);
			}
			$order['commission'] = $first_money+$second_price;
			$order->save();
		}
		*/
	}

	/**
     * 启动ticket推送服务
     */
    function startTicket($component_appid,$component_secret)
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_start_push_ticket';
        $data = [
            'component_appid' => $component_appid,
            'component_secret' => $component_secret
        ];
        http_post($url,$data);
        return true;
    }


    /**
     * 设置服务器域名
     */
    function setServedomain($domain)
    {
        $domain = explode(';',$domain);
        $requestdomain = [];//request 合法域名
        $wsrequestdomain = [];//socket 合法域名
        for($n=0;$n<sizeof($domain);$n++){
            $requestdomain[$n] = 'https://'.$domain[$n];
            $wsrequestdomain[$n] = 'wss://'.$domain[$n];
        }
        $access_token = getAccessToken();
        $url = 'https://api.weixin.qq.com/wxa/modify_domain?access_token='.$access_token;
        $data = [
            'action' => 'set',
            'requestdomain' => $requestdomain,
            'wsrequestdomain' => $wsrequestdomain,
            'uploaddomain' => $requestdomain,
            'downloaddomain' => $requestdomain
        ];
        return json_decode(http_post($url,$data),true);
    }

    /**
     * 设置功能介绍
     */
    function setSignature($signature)
    {
        $access_token = getAccessToken();
		$url = 'https://api.weixin.qq.com/cgi-bin/account/modifysignature?access_token='.$access_token;
		$data = ['signature' => $signature];
		return json_decode(http_post($url,$data),true);
    }
    
	/**
     * 获取已设置的所有类目
     */
	function getCategory()
	{
		$access_token = getAccessToken();
		$url = 'https://api.weixin.qq.com/cgi-bin/wxopen/getcategory?access_token='.$access_token;
		$result = json_decode(curl($url),true);
		if($result['errcode']==0 AND sizeof($result['categories'])>0){
			return $result;
			//common/model/category_serve.php 
		}
		return false;
	}
	
	/**
	* 验证是否添加小程序餐饮服务目录
	*/
	function is_food_category()
	{
		$access_token = getAccessToken();
		$url = 'https://api.weixin.qq.com/cgi-bin/wxopen/getcategory?access_token='.$access_token;
		$res = json_decode(curl($url),true);
		$msg = '未添加餐饮服务场所类目或类目未通过审核';
		if($res['errcode']!=0){
			return $msg;
		}
		for($n=0;$n<sizeof($res['categories']);$n++){
			if($res['categories'][$n]['first']==220 AND $res['categories'][$n]['second']==632 AND $res['categories'][$n]['audit_status']==3){
				return false;
			}
		}
		return $msg;
	}
	
	/**
     * 获取令牌 - 开放平台
	 * $type 请求类型 1商户小程序，0公众号
    */
	function getAccessToken($wxapp_id='',$type=1)
	{
		$config = ConfigModel::detail();	//获取第三方配置
		if($type==1){
			//商户小程序
			if(empty($wxapp_id)){
				$wxapp = WxappModel::detail();
			}else{
				$wxapp = WxappModel::getWxapp(['wxapp_id' => $wxapp_id]);
			}
			if($wxapp['is_empower']['value']==0){
				return false;	//未授权
			}
			$access_token=$wxapp['access_token'];
			if($wxapp['expires_in'] < time()){
				//重新获取
				$url = 'https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token='.$config['component_access_token'];
				$data = [
					'component_appid' => $config['app_id'],
					'authorizer_appid' => $wxapp['app_id'],
					'authorizer_refresh_token' => $wxapp['authorizer_refresh_token']
				];
				$token = json_decode(http_post($url,$data),true);
				if(isset($token['authorizer_access_token'])){
					$access_token = $token['authorizer_access_token'];
					$wxapp->access_token = $token['authorizer_access_token'];
					$wxapp->expires_in = time()+3600; //2个小时候过期，这里设置1小时获取一次
					$wxapp->save();//保存最新的令牌access_token和过期时间
				}
			}
		}else{
			//公众号
			empty($wxapp_id) && $wxapp_id = 0;
			$wechat = WechatModel::getWechat(['wxapp_id' => $wxapp_id]);	//获取第三方配置
			$access_token=$wechat['access_token'];
			if($wechat['expires_in'] < time()){
				//重新获取
				$url = 'https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token='.$config['component_access_token'];
				$data = [
					'component_appid' => $config['app_id'],
					'authorizer_appid' => $wechat['app_id'],
					'authorizer_refresh_token' => $wechat['authorizer_refresh_token']
				];
				$token = json_decode(http_post($url,$data),true);
				if(isset($token['authorizer_access_token'])){
					$access_token = $token['authorizer_access_token'];
					$wechat->access_token = $token['authorizer_access_token'];
					$wechat->expires_in = time()+3600; //2个小时候过期，这里设置1小时获取一次
					$wechat->save();//保存最新的令牌access_token和过期时间
				}
			}			
		}
		return $access_token;
	}
	
	/**
     * 发布已通过审核的小程序
     */
	function release($wxapp_id='')
	{
		$access_token = getAccessToken($wxapp_id);
		$url = 'https://api.weixin.qq.com/wxa/release?access_token='.$access_token;
		$result = json_decode(http_post($url),true);
		if($result['errcode'] == 0){
			return false;
		}
		return $result['errcode'];
	}
	
	/**
	* 获取预授权码 - 生成授权页面
	* $type，1=授权公众号，2=授权小程序，3=两者都有
	*/
	function authUrl($type=3,$wxapp_id=0)
	{
		$config = ConfigModel::detail();	//获取第三方配置
		if(empty($config['authorize_domain'])){
			$redirect_uri = web_url();
		}else{
			$redirect_uri = 'https://'.$config['authorize_domain'].'/';
		}
		$redirect_uri .= 'index.php?s=/task/auth/';
		if($type==1){
			$redirect_uri .= 'wechat/wxapp_id/'.$wxapp_id;
		}else{
			$redirect_uri .= 'wxapp/wxapp_id/'.$wxapp_id;
		}
		$url = 'https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token='.$config['component_access_token'];
		$data = [
			'component_appid' => $config['app_id']
		];
		$result = json_decode(http_post($url,$data),true);//返回"pre_auth_code": "预授权码","expires_in": 有效期（600秒）
		$url = 'https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid='.$config['app_id'].'&pre_auth_code='.$result['pre_auth_code'].'&redirect_uri='.$redirect_uri.'&auth_type='.$type;
		return $url;
	}

	/**
	 * 获取授权信息
	*/
	function getAuth($appid, $access_token, $auth_code)
	{
		$url = 'https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token='.$access_token;
		$data = [
			'component_appid' => $appid,
			'authorization_code' => $auth_code
		];
		$result = json_decode(http_post($url,$data),true);	
		return $result;
	}

	/**
	 * 获取授权应用的帐号基本信息
	*/
	function getAppInfo($auth_appid='', $appid='', $access_token='' )
	{
		if(empty($auth_appid)){
			$wxapp = WxappModel::detail();
			$auth_appid = $wxapp['app_id'];
		}
		if(empty($appid) OR empty($access_token)){
			$config = ConfigModel::detail();	//获取第三方配置
			$appid = $config['app_id'];
			$access_token = $config['component_access_token'];
		}
		$url = 'https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token='.$access_token;
		$data = [
			'component_appid' => $appid,
			'authorizer_appid' => $auth_appid
		];
		$result = json_decode(http_post($url,$data),true);
		return $result;
	}
	
	/**
	* 上传临时素材
	*/
	function up_temp_material($file_name)
	{
		$access_token = getAccessToken();
		$real_path = WEB_PATH . 'uploads/'.$file_name;
		$url = 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token='.$access_token.'&type=image';
		$data['media'] = curl_file_create($real_path,'image/jpeg',$file_name);//获取要上传的二进制文件
		$result = json_decode(http_post($url,$data),true);
		if(isset($result['media_id'])){
			return $result['media_id']; //返回的临时素材（media_id）			
		}else{
			return false;
		}
	}
	
	/**
	 * 永久素材
     * 上传图文消息内的图片 - 到微信端
	 *	图片仅支持jpg/png格式，大小必须在1MB以下
     */
    function upWechatUrl($file_name)
    {
        $access_token = getAccessToken();
		$real_path = WEB_PATH . 'uploads/'.$file_name;
		//上传到微信服务器
		$url = 'https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token='.$access_token;
		$post['media'] = curl_file_create($real_path,'image/jpeg',$file_name);//获取要上传的二进制文件
		$res = json_decode(http_post($url,$post),true);
		if(!isset($res['url'])){
			return false;//上传错误，一般是图片不符合要求
		}
		return $res['url'];
    }
	
	/**
     * 获取公众号粉丝用户基本信息（包括UnionID机制）- 公众号
    */
	function getWechatUserInfo($openid,$wxapp_id)
	{
		$access_token = getAccessToken($wxapp_id,0);
		$url = 'https://api.weixin.qq.com/cgi-bin/user/info';
		$result = json_decode(curl($url, [
	            'access_token' => $access_token,
	            'openid' => $openid,
	            'lang' => 'zh_CN'
	    ]),true);
		if(isset($result['unionid'])){
			$union_id = $result['unionid'];
		}else{
			if($wxapp_id<1){
				return false;
			}
			$union_id = '';
		}
		return [
			'union_id' => $union_id,
			'wechat_open_id' => $result['openid'],
			'nickName' => preg_replace('/[\xf0-\xf7].{3}/', '', $result['nickname']),
			'avatarUrl' => $result['headimgurl'],
			'gender' => $result['sex'],
			'country' => $result['country'],
			'province' => $result['province'],
			'city' => $result['city']
		];
	}
	
	/**
	* 验证手机号是否正确
	*/
	function isMobile($mobile) {
		if (!is_numeric($mobile)) {
			return false;
		}
		return preg_match('#^13[\d]{9}$|^14[5,7]{1}\d{8}$|^15[^4]{1}\d{8}$|^17[0,3,6,7,8]{1}\d{8}$|^18[\d]{9}$#', $mobile) ? true : false;
	}

	/**
	 * 生成订单号
	 */
	function orderNo()
	{
		return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
	}
	
	/**
     * 计算距离
	 * $from 起点，$to 终点
	 * $mode 计算方式：driving（驾车）、walking（步行）
     */
	function getDistance($from,$to,$mode='driving'){
		$values = WebSet::getItem('web');	//获取配置
		$key = $values['wxmap'];
		$url = 'https://apis.map.qq.com/ws/distance/v1/?parameters';
        $result = json_decode(curl($url, [
            'mode' => $mode,
			'from' => $from,
            'to' => $to,
            'key' => $key            
        ]), true);
        if ($result['status']!=0) {
            return false;
        }
        return $result['result']['elements'];
	}
	
	/**
     * 逆地址解析(坐标位置描述)
     */
	function getLocation($location){
		$values = WebSet::getItem('web');	//获取配置
		$key = $values['wxmap'];
		$url = 'https://apis.map.qq.com/ws/geocoder/v1/?location='.$location.'&key='.$key.'&get_poi=1';
        $result = json_decode(curl($url), true);
        if ($result['status']!=0) {
            return false;
        }
        $result['result']['address_component']['poi_id'] = '';
        //获取poi_id
        if(isset($result['result']['pois'][0])){
        	$result['result']['address_component']['poi_id'] = $result['result']['pois'][0]['id'];
        }
        return $result['result']['address_component'];
	}
	
	/**
     * 将xml转为array
    */
	function _xmlToArr($xml) {
        $res = @simplexml_load_string ( $xml,NULL, LIBXML_NOCDATA );
        $res = json_decode ( json_encode ( $res), true );
        return $res;
    }
	
	/**
	 * 生成圆形图片
	 * @param $imgpath  图片地址/支持微信、QQ头像等没有后缀的网络图
	 * @param $saveName string 保存文件名，默认空。
	 * @return resource 返回图片资源或保存文件
	 */
	function yuan_img($imgpath) {
		$src_img = imagecreatefromstring(file_get_contents($imgpath));
		$w = imagesx($src_img);$h = imagesy($src_img);
		$w = $h = min($w, $h);
		imagesavealpha($src_img, true); //保留透明背景
		$img = imagecreatetruecolor($w, $h);//生成画布默认黑色
		imagealphablending($img,false); //保留透明背景
		//这一句一定要有
		imagesavealpha($img, true);
		//拾取一个完全透明的颜色,最后一个参数127为全透明
		$bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
		imagefill($img, 0, 0, $bg);
		$r   = $w / 2; //圆半径
		for ($x = 0; $x < $w; $x++) {
			for ($y = 0; $y < $h; $y++) {
				$rgbColor = imagecolorat($src_img, $x, $y);
				if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
					imagesetpixel($img, $x, $y, $rgbColor);
				}
			}
		}
		//输出图片到文件
		imagepng ($img,$imgpath);
		//释放空间
		imagedestroy($src_img);
		imagedestroy($img);
	}

	/**
	 * 生成门店订单排号(取餐码)
	 */
	function rowNo($wxapp_id,$shop_id)
	{
		if($row_no = Cache::get('order_row_no_'.$wxapp_id.'_'.$shop_id)){
			$row_no = (int)$row_no;
			$row_no++;	
		}else{
			$row_no = 1;
		}
		//有效期时间,截至到当天23:59:59
		$time = strtotime(date('Y-m-d').'23:59:59')-time();
		Cache::set('order_row_no_'.$wxapp_id.'_'.$shop_id, $row_no,$time);
		$str_row_no = (string)$row_no;
		$lan = strlen($str_row_no);
		for($n=$lan;$n<4;$n++){
			$str_row_no = '0'.$str_row_no;
		}
		return $str_row_no;
	}

	/**
	 * 生成二维码
	 */
	function qrCode($shop_id=null,$table_id=null,$user_id=null)
	{
		if($shop_id){
			//生成门店二维码
			$scene = 'shop,'.$shop_id;	
			$path = 'assets/qrcode/shop';
			$file_name = $shop_id.'.png';
		}
		if($shop_id AND $table_id){
			//生成桌面二维码
			$scene = 'table,'.$shop_id.','.$table_id;
			$path = 'assets/qrcode/table';
			$file_name = $table_id.'.png';
		}
		if($user_id){
			//生成用户二维码
			$scene = 'user,'.$user_id;
			$path = 'assets/poster/temp/user';
			$file_name = $user_id.'.png';
		}
		$access_token = getAccessToken();
		$url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token='.$access_token;
		$data = ['scene' => $scene];
		$result = http_post($url,$data);
		$qr = json_decode($result,true);
		if(isset($qr['errcode'])){
			return $qr;
		}
		if(!file_exists($path)){
			mkdir($path,0777,true);
		} 
		file_put_contents($path.'/'.$file_name,$result); 
		//获取的二维码数据存储到指定的文件
		return false;
	}

	/**
	 * 打印调试函数
	 */
	function pre($content, $is_die = true)
	{
		header('Content-type: text/html; charset=utf-8');
		echo '<pre>' . print_r($content, true);
		$is_die && die();
	}

	/**
	 * 驼峰命名转下划线命名
	 */
	function toUnderScore($str)
	{
		$dstr = preg_replace_callback('/([A-Z]+)/', function ($matchs) {
			return '_' . strtolower($matchs[0]);
		}, $str);
		return trim(preg_replace('/_{2,}/', '_', $dstr), '_');
	}

	/**
	 * 生成密码hash值
	 */
	function hema_hash($password)
	{
		return md5(md5($password) . 'hema_salt_SmTRx');
	}

	/**
	 * 获取api接口域名(小程序服务器域名)
	 */
	function api_url()
	{
		$config = ConfigModel::detail();	//获取第三方配置
		$domain = explode(';',$config['api_domain']);
		return 'https://'.$domain[0].'/';
	}
	
	/**
	 * 获取当前站点域名
	 */
	function web_url()
	{
		$request = Request::instance();
		$subDir = str_replace('\\', '/', dirname($request->server('PHP_SELF')));
		return $request->scheme() . '://' . $request->host() . $subDir . ($subDir === '/' ? '' : '/');
	}

	/**
	 * 写入日志
	 */
	function write_log($values, $dir)
	{
		if (is_array($values))
			$values = print_r($values, true);
		// 日志内容
		$content = '[' . date('Y-m-d H:i:s') . ']' . PHP_EOL . $values . PHP_EOL . PHP_EOL;
		try {
			// 文件路径
			$filePath = $dir . '/logs/';
			// 路径不存在则创建
			!is_dir($filePath) && mkdir($filePath, 0755, true);
			// 写入文件
			return file_put_contents($filePath . date('Ymd') . '.log', $content, FILE_APPEND);
		} catch (\Exception $e) {
			return false;
		}
	}

	/**
	 * curl请求指定url(POST请求)
	 * $url请求的URL
	 * $data 请求传递的数据
	 */
	function http_post($url,$data = array(),$headers=array())
	{
		$curl = curl_init();
		if( count($headers) >= 1 ){
			curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
		}
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

		if (count($data) >= 1 AND !isset($data['media'])){
			$data = json_encode($data,JSON_UNESCAPED_UNICODE);
		}elseif(count($data) == 0){
			$data = '{}';
		}
		curl_setopt($curl, CURLOPT_POST, 1);
		curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$output = curl_exec($curl);
		$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
		curl_close($curl);
		return $output;
	}

	/**
	 * curl请求指定url
	 */
	function curl($url, $data = [],$headers=array())
	{
		// 处理get数据
		if (!empty($data)) {
			$url = $url . '?' . http_build_query($data);
		}
		$curl = curl_init();
		if( count($headers) >= 1 ){
			curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
		}
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_HEADER, false);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//这个是重点。
		$result = curl_exec($curl);
		curl_close($curl);
		return $result;
	}

	if (!function_exists('array_column')) {
		/**
		 * array_column 兼容低版本php
		 * (PHP < 5.5.0)
		 * @param $array
		 * @param $columnKey
		 * @param null $indexKey
		 * @return array
		 */
		function array_column($array, $columnKey, $indexKey = null)
		{
			$result = array();
			foreach ($array as $subArray) {
				if (is_null($indexKey) && array_key_exists($columnKey, $subArray)) {
					$result[] = is_object($subArray) ? $subArray->$columnKey : $subArray[$columnKey];
				} elseif (array_key_exists($indexKey, $subArray)) {
					if (is_null($columnKey)) {
						$index = is_object($subArray) ? $subArray->$indexKey : $subArray[$indexKey];
						$result[$index] = $subArray;
					} elseif (array_key_exists($columnKey, $subArray)) {
						$index = is_object($subArray) ? $subArray->$indexKey : $subArray[$indexKey];
						$result[$index] = is_object($subArray) ? $subArray->$columnKey : $subArray[$columnKey];
					}
				}
			}
			return $result;
		}
	}

	/**
	 * 多维数组合并
	 */
	function array_merge_multiple($array1, $array2)
	{
		$merge = $array1 + $array2;
		$data = [];
		foreach ($merge as $key => $val) {
			if (
				isset($array1[$key])
				&& is_array($array1[$key])
				&& isset($array2[$key])
				&& is_array($array2[$key])
			) {
				$data[$key] = array_merge_multiple($array1[$key], $array2[$key]);
			} else {
				$data[$key] = isset($array2[$key]) ? $array2[$key] : $array1[$key];
			}
		}
		return $data;
	}

	/**
	 * 获取全局唯一标识符
	 */
	function getGuidV4($trim = true)
	{
		// Windows
		if (function_exists('com_create_guid') === true) {
			$charid = com_create_guid();
			return $trim == true ? trim($charid, '{}') : $charid;
		}
		// OSX/Linux
		if (function_exists('openssl_random_pseudo_bytes') === true) {
			$data = openssl_random_pseudo_bytes(16);
			$data[6] = chr(ord($data[6]) & 0x0f | 0x40);    // set version to 0100
			$data[8] = chr(ord($data[8]) & 0x3f | 0x80);    // set bits 6-7 to 10
			return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
		}
		// Fallback (PHP 4.2+)
		mt_srand((double)microtime() * 10000);
		$charid = strtolower(md5(uniqid(rand(), true)));
		$hyphen = chr(45);                  // "-"
		$lbrace = $trim ? "" : chr(123);    // "{"
		$rbrace = $trim ? "" : chr(125);    // "}"
		$guidv4 = $lbrace .
			substr($charid, 0, 8) . $hyphen .
			substr($charid, 8, 4) . $hyphen .
			substr($charid, 12, 4) . $hyphen .
			substr($charid, 16, 4) . $hyphen .
			substr($charid, 20, 12) .
			$rbrace;
		return $guidv4;
	}

	/**
     * 第一步：上传小程序模板
     */
	function publish($wxapp, $template) 
	{
		$access_token = getAccessToken($wxapp['wxapp_id']);
		$url = 'https://api.weixin.qq.com/wxa/commit?access_token='.$access_token;
		$ext = [
			'extEnable' => true,
			'extAppid' => $wxapp['app_id'],
			'directCommit' => false,
			'ext' => [
				'wxapp_id' => $wxapp['wxapp_id'],
				'api_url' => api_url()
			]
		];
		/*
		//如果小程序开通直播
		if($wxapp['is_live']==1){
			$plugins = WebWxappPluginsModel::getPlugins(['key' => 'live']);
			$ext['plugins'] = [
				'live-player-plugin' => [
					'version' => $plugins['user_version'],
					'provider' => $plugins['plugin_appid']
				]
			];
		}*/
		$data = [
			'template_id' => $template['id'],
			'ext_json' => json_encode($ext),
			'user_version' => $template['user_version'],
			'user_desc' => $template['user_desc']
		];
		$result = json_decode(http_post($url,$data),true);	
		if($result['errcode'] == 0){
			return false;
		}
		return $result['errcode'];	
	}

	/**
     * 第二步：提交审核小程序模板
     */
	function audit($wxapp_id)
	{
		$access_token = getAccessToken($wxapp_id);
		$url = 'https://api.weixin.qq.com/wxa/submit_audit?access_token='.$access_token;
		return json_decode(http_post($url),true);
	}

	/**
     * 获取指定版本的审核状态 - 小程序代码模板
     */
	function getAuditStatus($auditid,$wxapp_id=''){
		$access_token = getAccessToken($wxapp_id);
		$url = 'https://api.weixin.qq.com/wxa/get_auditstatus?access_token='.$access_token;
		$data = [
			'auditid' => $auditid
		];
		return json_decode(http_post($url,$data),true);
	}

	/**
     * 获取规格信息
     */
    function getManySpecData($spec_rel, $skuData)
    {
        // spec_attr
        $specAttrData = [];
        foreach ($spec_rel->toArray() as $item) {
            if (!isset($specAttrData[$item['spec_id']])) {
                $specAttrData[$item['spec_id']] = [
                    'group_id' => $item['spec']['spec_id'],
                    'group_name' => $item['spec']['spec_name'],
                    'spec_items' => [],
                ];
            }
            $specAttrData[$item['spec_id']]['spec_items'][] = [
                'item_id' => $item['spec_value_id'],
                'spec_value' => $item['spec_value'],
            ];
        }

        // spec_list
        $specListData = [];
        foreach ($skuData->toArray() as $item) {
            $image = (isset($item['image']) && !empty($item['image'])) ? $item['image'] : ['file_id' => 0, 'file_path' => ''];
            $specListData[] = [
                'goods_spec_id' => $item['goods_spec_id'],
                'spec_sku_id' => $item['spec_sku_id'],
                'rows' => [],
                'form' => [
                    'image_id' => $image['file_id'],
                    'image_path' => $image['file_path'],
                    'goods_no' => $item['goods_no'],
                    'goods_price' => $item['goods_price'],
                    'line_price' => $item['line_price'],
                    'stock_num' => $item['stock_num'],
                    'seckill_price' => $item['seckill_price'],
                    'seckill_stock_num' => $item['seckill_stock_num'],
                    'group_price' => $item['group_price'],
                    'group_stock_num' => $item['group_stock_num'],
                    'bargain_price' => $item['bargain_price'],
                    'bargain_stock_num' => $item['bargain_stock_num'],
                    'goods_weight' => $item['goods_weight']
                ],
            ];
        }
        return ['spec_attr' => array_values($specAttrData), 'spec_list' => $specListData];
    }

	/**
	 * 微信错误返回 ,插件
	*/
	function wx_err_msg($errcode)
	{
		if($errcode == -1){
			return '-1：系统错误/繁忙/非法action参数';
		}
		if($res = WechatErr::detail($errcode)){
			return 'Code：'.$errcode.'，msg：'.$res['errmsg'];
		}
		return $errcode.'：未知错误';
	}
	
	/**
     * 构建微信支付 - 商户统一下单
     */
    function wxPay($wxapp_id=0,$order_no, $open_id='', $pay_price, $type='',$body='')
    {
    	if($wxapp_id > 0){
    		$values = SettingModel::getItem('payment',$wxapp_id);
    		$config = $values['wx'];
    		$wxapp = WxappModel::detail();
    		$config['app_id'] = $wxapp['app_id'];
    	}else{
    		$values = WebSet::getItem('payment');
    		$config = $values['wx'];
    		$config['is_sub'] = 0;
    		$values = WebSet::getItem('outapp');
    		$config['app_id'] = $values['wx']['app_id'];
    	}
    	//判断是否为公众号支付
    	if($type == 'MWEB'){
    		$wechat = WechatModel::detail();
    		$config['app_id'] = $wechat['app_id'];
    	}
        $WxPay = new WxPay($config);
        return $WxPay->unifiedorder($order_no, $open_id, $pay_price,$type,$body);
    }

    /**
     * 多维数组按照指定字段升/降序排列
     */
    function arrSort($data,$field,$order='desc')
    {
    	foreach($data as $val){
			$key_arrays[]=$val[$field];
		}
    	if($order='desc'){
    		array_multisort($key_arrays,SORT_DESC,SORT_NUMERIC,$data);
    	}else{
    		array_multisort($key_arrays,SORT_ASC,SORT_NUMERIC,$data);
    	}
		return $data;
    }

    /**
	 * 获取当前系统版本号
	 */
	function get_version()
	{
	    return json_decode(file_get_contents('./application/version.json'), true);
	}

	/**
	 * 清空缓存目录
	 */
	function deldir($path){
	    //如果是目录则继续
	    if(is_dir($path)){
	        //扫描一个文件夹内的所有文件夹和文件并返回数组
	        $p = scandir($path);
	        foreach($p as $val){
	            //排除目录中的.和..
	            if($val !="." && $val !=".."){
	                //如果是目录则递归子目录，继续操作
	                if(is_dir($path.$val)){
	                    //子目录中操作删除文件夹和文件
	                    deldir($path.$val.'/');
	                    //目录清空后删除空文件夹
	                    @rmdir($path.$val.'/');
	                }else{
	                    //如果是文件直接删除
	                    unlink($path.$val);
	                }
	            }
	        }
	    }
	}
